1. Field of the Invention
This invention relates in general to the field of microelectronics, and more particularly to a technique for incorporating interrupt suppression features at the instruction level into an existing microprocessor instruction set architecture.
2. Description of the Related Art
Since microprocessors were fielded in the early 1970's, their use has grown exponentially. Originally applied in the scientific and technical fields, microprocessor use has moved over time from those specialty fields into commercial consumer fields that include products such as desktop and laptop computers, video game controllers, and many other common household and business devices.
Along with this explosive growth in use, the art has experienced a corresponding technology pull that is characterized by an escalating demand for increased speed, expanded addressing capabilities, faster memory accesses, larger operand size, more types of general purpose operations (e.g., floating point, single-instruction multiple data (SIMD), conditional moves, etc.), and added special purpose operations (e.g., digital signal processing functions and other multi-media operations). This technology pull has resulted in an incredible number of advances in the art which have been incorporated in microprocessor designs such as extensive pipelining, super-scalar architectures, cache structures, out-of-order processing, burst access mechanisms, branch prediction, and speculative execution. Quite frankly, a present day microprocessor is an amazingly complex and capable machine in comparison to its 30-year-old predecessors.
But unlike many other products, there is another very important factor that has constrained, and continues to constrain, the evolution of microprocessor architecture. This factor—legacy compatibility—accounts for much of the complexity that is present in a modern microprocessor. For market-driven reasons, many producers have opted to retain all of the capabilities that are required to insure compatibility with older, so-called legacy application programs as new designs are provided which incorporate new architectural features.
Nowhere has this legacy compatibility burden been more noticeable than in the development history of x86-compatable microprocessors. It is well known that a present day virtual-mode, 32-/16-bit x86 microprocessor is still capable of executing 8-bit, real-mode, application programs which were produced during the 1980's. And those skilled in the art will also acknowledge that a significant amount of corresponding architectural “baggage” is carried along in the x86 architecture for the sole purpose of retaining compatibility with legacy applications and operating modes. Yet while in the past developers have been able to incorporate newly developed architectural features into existing instruction set architectures, the means whereby use of these features is enabled—programmable instructions—have become scarce. More specifically, there are no “spare” instructions in certain instruction sets of interest that provide designers with a way to incorporate newer features into an existing architecture.
In the x86 instruction set architecture, for example, there are no remaining undefined 1-byte opcode values. All 256 opcode values in the primary 1-byte x86 opcode map are taken up with existing instructions. As a result, x86 microprocessor designers today must choose either to provide new features or to retain legacy compatibility. If new programmable features are to be provided, then they must be assigned to opcode values in order for programmers to exercise those features. And if spare opcode values do not remain in an existing instruction set architecture, then some of the existing opcode values must be redefined to provide for specification of the new features. Thus, legacy compatibility is sacrificed in order to make way for new feature growth.
There are a number of features that programmers desire in a present day microprocessor, but which have heretofore been precluded from incorporation because of the aforementioned reasons. One particular feature that is desirable for incorporation is interrupt suppression control at the instruction level.
Interrupts are employed in a present day microprocessor to couple the microprocessor to external devices that have time-critical interface requirements. Ordinarily, application programs execute on a microprocessor uninterrupted. And when an external device, such as a disk drive or network adapter, requires servicing by the microprocessor, the external device asserts an interrupt signal that is either directly or indirectly provided to the microprocessor to indicate that an event has occurred which requires a timely response. Accordingly, most microprocessors include provisions for interrupting normal program execution in order to service these external devices. Following processing of an interrupt, program control is normally returned to the point at which an executing program was interrupted.
Most present day microprocessors have one or more external interrupt signal pins that can be directly coupled to an external device or that can indirectly coupled to a number of external devices through a special purpose logic device called an interrupt controller. For the purposes of this application, it is sufficient to note that a typical interrupt controller is configured to communicate with its host microprocessor in such a manner as to provide a means for interfacing a significant number of external devices to the microprocessor via a small number of interrupt signal pins. For example, through a typical interrupt controller that communicates with a given microprocessor over two interrupt signal pins, over 200 external devices can assert interrupts to the given microprocessor, each of which are individually distinguished and serviced by the given microprocessor.
The processing of interrupts is a very complex task. When an interrupt occurs, a currently executing application program must be interrupted at a point where the state of execution can be saved during the period that the interrupt is being processed so that its state can be subsequently restored and program execution is allowed to continue. The state of an executing program is typically reflected in terms of the execution point, or instruction address, at which operation is suspended along with the values of all general purpose and system status registers that are associated with the executing program. Accordingly, when an interrupt occurs, it is necessary to allow a the currently executing program to complete execution of a current instruction, then to suspend operation of the program while saving a copy of the program's general purpose and system status registers along with the address of the next instruction that follows the current instruction. After these parameters are saved, program control in the microprocessor typically branches to an interrupt handler (also known as an exception handler) application that is generally part of the operating system program. The interrupt handler initiates transactions external to the microprocessor (typically over a system bus) to determine which external device asserted the interrupt signal pins. Upon determination, program flow is then diverted to a specific interrupt service application that performs those operations which are required to “service” the external device. Servicing the external device can involve virtually any type of operation such as reading or writing data to the device, updating special registers internal to the microprocessor, transferring blocks of data to or from memory, etc. When the interrupt has been serviced, then control is returned to the operating system which, in turn, restores the saved state of the interrupted application program and then transfers program control to the address of the next instruction.
The above description of interrupt processing is provided to enable the reader to appreciate the operations that are required to process a typical interrupt in a typical pipeline microprocessor. One skilled in the art will understand that individual microprocessor architectures differ in terms of the number of interrupt signal pins provided, the manner in which those signals are asserted, how devices communicate interrupts, the hierarchy of interrupts, the specifics of preserving and restoring the “state” of an interrupted application, at what point the application is suspended after an interrupt occurs, and the particular operating details of interrupt handlers that are provided for by each individual microprocessor architecture.
Because the handling of interrupts is so complex, present day microprocessors provide mechanisms that enable interrupt processing to be restricted to the operating system level. For instance, many microprocessor architectures have a programmable register to allow interrupts to be ignored when they occur. In an x86-compatable microprocessor, this programmable register takes the form of an interrupt enable flag bit within an x86 flags register internal to the x86-compatible microprocessor. When this bit is asserted, interrupts are processed. When this bit is not asserted, interrupts are ignored. This level of programmable control is provided to enable programmers to ensure that certain operations (i.e., certain sequences of instructions) can be accomplished without being interrupted. For example, when a particular interrupt occurs, the interrupt handler within an operating system will typically disable interrupts (via the flag bit) while the particular interrupt is being processed. After the particular interrupt is processed, the interrupt handler will set the interrupt enable bit, thus allowing any pending interrupts to be processed accordingly. To restrict programs other than the operating system from disabling and enabling interrupt processing, microprocessor architectures also provide a mechanism for precluding application programs from executing instructions that affect whether interrupts are enabled or disabled. An x86-compatable microprocessor allows programmers to assign one of four privilege levels to all programs executing on the microprocessor. Operating systems are typically assigned to the highest privilege level and application programs are assigned to the lowest privilege level. If an application program running at the lowest privilege level attempts to execute an instruction to disable interrupts, the x86 processor will detect this event and will prevent the instruction from being executed. Other microprocessor architectures employ different mechanisms for restricting control of interrupt processing only to those applications that are responsible for such tasks. It is sufficient herein to appreciate that the complex nature of interrupt processing in a present day microprocessor has resulted in features that preclude application programmers from determining if and when their application programs are suspended to for interrupt processing.
But there are a significant number of operations performed by application programs that require the uninterrupted execution of more than one program instruction. For example, in a system configuration that shares memory between a microprocessor and other devices, a multiple-instruction task that reads a value from a memory location, modifies the value, and writes the modified value back to the memory location could conceivably fail if the multiple-instruction task is interrupted after the value has been read from memory but prior to writing the value back to memory. This type of operation is referred to as a read-modify-write operation. Read-modify-write operations must be performed “atomically,” that is, without interruption, to ensure proper program performance. As such, some microprocessor architectures provide a limited number of instructions that accomplish common atomic operations. In the x86 instruction set, a compare and exchange instruction (CMPXCHG) is provided that allows a programmer to direct a microprocessor to atomically compare a first operand read from a memory location to a register operand and, based upon the comparison result, to write either the first or the register operand back to the memory location. Another atomic instruction, XADD, enables a programmer to direct a microprocessor to read a first operand from a memory location, to exchange the first operand with a register operand, and to write the sum of the two operands back to the memory location.
Hence, some of the more common atomic operations that are required by application programs are provided for by atomic instructions within certain microprocessor instruction sets. Yet, there remain many other operations performed at the application program level that presently fail under the presence of interrupts because the operations require uninterrupted execution of a sequence of operations or instructions, yet application programmers have no way of ensuring that interrupts will not occur during the period when the sequence of operations or instructions is being executed. Application programmers are further limited to certain “atomic” instructions as alluded to above which may not effectively implement desired atomic operations because these atomic instructions are directed only to the performance of more common atomic operations.
Therefore, what is needed is an apparatus and method that incorporate suppression of interrupt features into an existing microprocessor architecture having a completely full opcode set, where incorporation of the interrupt suppression features allow a conforming microprocessor to retain the capability to execute legacy application programs while concurrently providing application programmers and/or compilers with the capability to control whether or not interrupt processing is performed on any given sequence of instructions.